home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_562 / intuisup / render / source.lzh / render.c < prev    next >
C/C++ Source or Header  |  1991-10-19  |  18KB  |  546 lines

  1.         /*************************************
  2.          *                                   *
  3.          *            Render v2.0            *
  4.          *   by Torsten Jürgeleit in 05/91   *
  5.          *                                   *
  6.          *              Routines             *
  7.          *                                   *
  8.          *************************************/
  9.  
  10.     /* Includes */
  11.  
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <intuition/intuition.h>
  15. #include <functions.h>
  16. #include "render.h"
  17.  
  18.     /* Defines */
  19.  
  20. #define RED_SCALE    3   /* amount of RGB values to take in account the different visual impact of those colors */
  21. #define GREEN_SCALE    6
  22. #define BLUE_SCALE    2
  23.  
  24.     /* Statics */
  25.  
  26. STATIC USHORT image_data_arrow_left[] = {   /* bitmap data for left arrow image */
  27.     0x0780, 0x3e00, 0xf800, 0x3e00, 0x0780, 0x0000, 0x0000, 0x0000,
  28.     0x0000, 0x0000
  29. };
  30. STATIC USHORT image_data_arrow_right[] = {   /* bitmap data for right arrow image */
  31.     0xf000, 0x3e00, 0x0f80, 0x3e00, 0xf000, 0x0000, 0x0000, 0x0000,
  32.     0x0000, 0x0000
  33. };
  34. STATIC USHORT image_data_arrow_up[] = {   /* bitmap data for up arrow image */
  35.     0x0800, 0x1c00, 0x3e00, 0x7700, 0xc180, 0x0000, 0x0000, 0x0000,
  36.     0x0000, 0x0000
  37. };
  38. STATIC USHORT image_data_arrow_down[] = {   /* bitmap data for down arrow image */
  39.     0xc180, 0x7700, 0x3e00, 0x1c00, 0x0800, 0x0000, 0x0000, 0x0000,
  40.     0x0000, 0x0000
  41. };
  42. STATIC USHORT image_data_toggle_knob_unselected[] = {   /* bitmap data for unselected toggle knob image */
  43.     0x1ffc, 0x0000, 0x7000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000,
  44.     0xc000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x7000, 0x0000,
  45.     0x1000, 0x0000,   /* Plane 0 */
  46.     0x0002, 0x0000, 0x0003, 0x8000, 0x0000, 0xc000,    0x0000, 0xc000,
  47.     0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0xc000,    0x0003, 0x8000,
  48.     0x0ffe, 0x0000    /* Plane 1 */
  49. };
  50. STATIC USHORT image_data_toggle_knob_selected[] = {   /* bitmap data for selected toggle knob image */
  51.     0x0002, 0x0000, 0x0003, 0x8000, 0x03f0, 0xc000, 0x0ffc, 0xc000,
  52.     0x0ffc, 0xc000, 0x0ffc, 0xc000, 0x03f0, 0xc000, 0x0003, 0x8000,
  53.     0x0ffe, 0x0000,   /* Plane 0 */
  54.     0x1ffc, 0x0000, 0x7000, 0x0000, 0xc3f0, 0x0000,    0xcffc, 0x0000,
  55.     0xcffc, 0x0000, 0xcffc, 0x0000, 0xc3f0, 0x0000,    0x7000, 0x0000,
  56.     0x1000, 0x0000    /* Plane 1 */
  57. };
  58. STATIC USHORT image_data_toggle_check_selected[] = {   /* bitmap data for selected toggle checkmark image */
  59.     0x0038, 0x0060, 0x00c0, 0xe180, 0x7300, 0x3e00, 0x1c00
  60. };
  61. STATIC USHORT image_data_cycle[] = {   /* bitmap data for cycle image */
  62.     0x7f01, 0xc181, 0xc181, 0xc7e1, 0xc3c1, 0xc181, 0xc001,    0xc181,
  63.     0x7f01,   /* Plane 0 */
  64.     0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
  65.     0x0002    /* Plane 1 */
  66. };
  67. STATIC USHORT image_data_count_left[] = {   /* bitmap data for left count image */
  68.     0x0700, 0x3f00, 0xff00, 0x3f00, 0x0700
  69. };
  70. STATIC USHORT image_data_count_right[] = {   /* bitmap data for right count image */
  71.     0xe000, 0xfc00, 0xff00, 0xfc00, 0xe000
  72. };
  73. STATIC struct Image  images[MAX_RENDER_IMAGES] = {
  74.    {        /* left arrow */
  75.     0, 0, IMAGE_ARROW_WIDTH, IMAGE_ARROW_HEIGHT, IMAGE_ARROW_DEPTH,
  76.     &image_data_arrow_left[0], 0, 0, NULL
  77.    }, {        /* right arrow */
  78.     0, 0, IMAGE_ARROW_WIDTH, IMAGE_ARROW_HEIGHT, IMAGE_ARROW_DEPTH,
  79.     &image_data_arrow_right[0], 0, 0, NULL
  80.    }, {        /* up arrow */
  81.     0, 0, IMAGE_ARROW_WIDTH, IMAGE_ARROW_HEIGHT, IMAGE_ARROW_DEPTH,
  82.     &image_data_arrow_up[0], 0, 0, NULL
  83.    }, {        /* down arrow */
  84.     0, 0, IMAGE_ARROW_WIDTH, IMAGE_ARROW_HEIGHT, IMAGE_ARROW_DEPTH,
  85.     &image_data_arrow_down[0], 0, 0, NULL
  86.    }, {        /* toggle select knob unselected */
  87.     0, 0, IMAGE_KNOB_WIDTH, IMAGE_KNOB_HEIGHT, IMAGE_KNOB_DEPTH,
  88.     &image_data_toggle_knob_unselected[0], 0, 0, NULL
  89.    }, {        /* toggle select knob selected */
  90.     0, 0, IMAGE_KNOB_WIDTH, IMAGE_KNOB_HEIGHT, IMAGE_KNOB_DEPTH,
  91.     &image_data_toggle_knob_selected[0], 0, 0, NULL
  92.    }, {        /* toggle select check unselected */
  93.     IMAGE_HORIZ_OFFSET, IMAGE_VERT_OFFSET, IMAGE_CHECK_WIDTH,
  94.     IMAGE_CHECK_HEIGHT, 0, NULL, 0, 0, NULL
  95.    }, {        /* toggle select check selected */
  96.     IMAGE_HORIZ_OFFSET, IMAGE_VERT_OFFSET, IMAGE_CHECK_WIDTH,
  97.     IMAGE_CHECK_HEIGHT, IMAGE_CHECK_DEPTH,
  98.     &image_data_toggle_check_selected[0], 0, 0, NULL
  99.    }, {        /* cycle */
  100.     0, 0, IMAGE_CYCLE_WIDTH, IMAGE_CYCLE_HEIGHT, IMAGE_CYCLE_DEPTH,
  101.     &image_data_cycle[0], 0, 0, NULL
  102.    }, {        /* left count */
  103.     0, 0, IMAGE_COUNT_WIDTH, IMAGE_COUNT_HEIGHT, IMAGE_COUNT_DEPTH,
  104.     &image_data_count_left[0], 0, 0, NULL
  105.    }, {        /* right count */
  106.     0, 0, IMAGE_COUNT_WIDTH, IMAGE_COUNT_HEIGHT, IMAGE_COUNT_DEPTH,
  107.     &image_data_count_right[0], 0, 0, NULL
  108.    }
  109. };
  110. STATIC struct TextAttr  topaz80_attr = { (STRPTR)"topaz.font", TOPAZ_EIGHTY,
  111.                            FS_NORMAL, FPF_ROMFONT };
  112.     /* Static prototypes */
  113.  
  114. SHORT calc_color_level(SHORT color);
  115. VOID  init_render_info_images(struct RenderInfo *ri);
  116. UBYTE get_image_pixel_color(struct Image  *image, USHORT x, USHORT y);
  117. VOID  set_image_pixel_color(struct Image  *image, USHORT x, USHORT y,
  118.                                    UBYTE color);
  119.     /* Static pragmas */
  120.  
  121. #pragma regcall(calc_color_level(d0))
  122. #pragma regcall(init_render_info_images(a0))
  123. #pragma regcall(get_image_pixel_color(a0,d0,d1))
  124. #pragma regcall(set_image_pixel_color(a0,d0,d1,d2))
  125.  
  126.     /* Get render info for given screen */
  127.  
  128.    struct RenderInfo  *
  129. get_render_info(struct Screen  *screen, USHORT flags)
  130. {
  131.    struct RenderInfo  *ri = NULL;
  132.    struct Screen      wb_screen;
  133.    struct ColorMap    *cmap;
  134.    struct Image       *image = &images[0];
  135.    USHORT *data;
  136.    ULONG  data_size = 0;
  137.    SHORT  i, j, temp, num_colors, back_color, colors[MAX_RENDER_COLORS],
  138.       color_levels[MAX_RENDER_COLORS], pens[MAX_RENDER_COLORS];
  139.  
  140.    if (ri = AllocMem((LONG)sizeof(struct RenderInfo),
  141.                       (LONG)MEMF_PUBLIC | MEMF_CLEAR)) {
  142.       /* If no screen given then use workbench screen */
  143.       if (! screen) {
  144.      GetScreenData((BYTE *)(screen = &wb_screen), (LONG)
  145.                   sizeof(struct Screen), (LONG)WBENCHSCREEN,
  146.                              (struct Screen *)NULL);
  147.       }
  148.  
  149.       /* Get screen and window data */
  150.       ri->ri_ScreenWidth        = screen->Width;
  151.       ri->ri_ScreenHeight       = screen->Height;
  152.       ri->ri_ScreenDepth        = screen->RastPort.BitMap->Depth;
  153.       ri->ri_WindowBorderTop    = screen->BarHeight -
  154.                        screen->BarVBorder + screen->WBorTop;
  155.       ri->ri_WindowBorderLeft   = screen->WBorLeft;
  156.       ri->ri_WindowBorderRight  = screen->WBorRight;
  157.       ri->ri_WindowBorderBottom = screen->WBorBottom;
  158.       ri->ri_Flags              = flags;
  159.  
  160.       /* Calc gadget chipmem data buffer size */
  161.       for (i = 0; i < MAX_RENDER_IMAGES; i++, image++) {
  162.      if (image->ImageData) {
  163.         data_size += (image->Width / 16 + (image->Width & 15 ? 1 : 0)) *
  164.                      image->Height * ri->ri_ScreenDepth * 2;
  165.      }
  166.       }
  167.       if (!(data = AllocMem(data_size, (LONG)MEMF_PUBLIC | MEMF_CHIP |
  168.                                  MEMF_CLEAR))) {
  169.      FreeMem(ri, (LONG)sizeof(struct RenderInfo));
  170.      ri = NULL;
  171.       } else {
  172.      /* Insert image data buffer and size */
  173.      ri->ri_ImageData     = data;
  174.      ri->ri_ImageDataSize = data_size;
  175.  
  176.      /* Open screen text font and clone screen text attr struct */
  177.      Forbid();
  178.      if (screen->Font) {
  179.         ri->ri_TextFont = OpenFont(screen->Font);
  180.      }
  181.      Permit();
  182.      if (ri->ri_TextFont) {
  183.         ri->ri_TextAttr.ta_Name  = (STRPTR)
  184.                 ri->ri_TextFont->tf_Message.mn_Node.ln_Name;
  185.         ri->ri_TextAttr.ta_YSize = ri->ri_TextFont->tf_YSize;
  186.         ri->ri_TextAttr.ta_Style = ri->ri_TextFont->tf_Style;
  187.         ri->ri_TextAttr.ta_Flags = ri->ri_TextFont->tf_Flags;
  188.      } else {
  189.         ri->ri_TextFont = OpenFont(&topaz80_attr);
  190.         CopyMem((BYTE *)&topaz80_attr, (BYTE *)&ri->ri_TextAttr, (LONG)
  191.                            sizeof(struct TextAttr));
  192.      }
  193.  
  194.      /* Examine screen colors */
  195.      if ((num_colors = 1 << ri->ri_ScreenDepth) > MAX_RENDER_COLORS) {
  196.         num_colors = MAX_RENDER_COLORS;
  197.      }
  198.      if (num_colors < 3) {
  199.  
  200.         /* Set render pens for monochrome screen */
  201.         ri->ri_HighlightPen = 1;
  202.         ri->ri_ShadowPen    = 1;
  203.         ri->ri_TextPen1     = 1;
  204.         ri->ri_TextPen2     = 1;
  205.         ri->ri_BackPen      = 0;
  206.      } else {
  207.  
  208.         /* Get current screen colors */
  209.         Forbid();
  210.         cmap = screen->ViewPort.ColorMap;
  211.         for (i = 0; i < num_colors; i++) {
  212.            colors[i]       = GetRGB4(cmap, (LONG)i);
  213.            color_levels[i] = calc_color_level(colors[i]);
  214.            pens[i]         = i;
  215.         }
  216.         Permit();
  217.  
  218.         /* Save normal background color */
  219.         back_color = colors[0];
  220.  
  221.         /* Sort colors darkest to brightest (BUBBLE SORT) */
  222.         for (i = 0; i < (num_colors - 1); i++) {
  223.            for (j = i + 1; j < num_colors; j++) {
  224.           if (color_levels[i] > color_levels[j]) {
  225.  
  226.              /* Swap colors, color levels and pens */
  227.              temp      = colors[i];
  228.              colors[i] = colors[j];
  229.              colors[j] = temp;
  230.  
  231.              temp            = color_levels[i];
  232.              color_levels[i] = color_levels[j];
  233.              color_levels[j] = temp;
  234.  
  235.              temp    = pens[i];
  236.              pens[i] = pens[j];
  237.              pens[j] = temp;
  238.           }
  239.            }
  240.         }
  241.         if (flags & RENDER_INFO_FLAG_BACK_FILL) {
  242.  
  243.            /* Set render pens - highlight pen first */
  244.            ri->ri_HighlightPen = pens[num_colors - 1];
  245.  
  246.            /* Set shadow pen */
  247.            ri->ri_ShadowPen = pens[0];
  248.  
  249.            /* Set back pen */
  250.            if (! pens[i = 1]) {   /* don't use normal background color */
  251.           i++;
  252.            }
  253.            ri->ri_BackPen = pens[i];
  254.            back_color     = colors[i];   /* new background color */
  255.         } else {
  256.  
  257.            /* Set render pens - highlight pen first */
  258.            if (! pens[i = num_colors - 1]) {   /* don't use normal background color */
  259.           i--;
  260.            }
  261.            ri->ri_HighlightPen = pens[i];
  262.  
  263.            /* Set shadow pen */
  264.            if (! pens[i = 0]) {
  265.           i++;
  266.            }
  267.            ri->ri_ShadowPen = pens[i];
  268.  
  269.            /* Set back pen */
  270.            ri->ri_BackPen = 0;
  271.         }
  272.  
  273.         /* Set text pen 1 */
  274.         for (i = 0, j = 0; i < num_colors; i++) {
  275.            if ((temp = calc_color_difference(colors[i],
  276.                              back_color)) > j) {
  277.           j               = temp;
  278.           ri->ri_TextPen1 = pens[i];
  279.            }
  280.         }
  281.  
  282.         /* Set text pen 2 */
  283.         for (i = 0, j = 0; i < num_colors; i++) {
  284.            if ((temp = calc_color_difference(colors[i],
  285.                back_color)) > j && pens[i] != ri->ri_TextPen1) {
  286.           j               = temp;
  287.           ri->ri_TextPen2 = pens[i];
  288.            }
  289.         }
  290.          }
  291.          init_render_info_images(ri);
  292.       }
  293.    }
  294.    return(ri);
  295. }
  296.     /* Calc color level with specified scaling values */
  297.  
  298.    STATIC SHORT
  299. calc_color_level(SHORT color)
  300. {
  301.    return(calc_color_difference(color, 0));
  302. }
  303.     /* Calc color difference with specified scaling values */
  304.  
  305.    SHORT   /* non static - needed by menus.c too */
  306. calc_color_difference(SHORT color1, SHORT color2)
  307. {
  308.    USHORT temp, diff;
  309.  
  310.    temp  = (color1 & 0x00f) - (color2 & 0x00f);
  311.    diff  = temp * temp * BLUE_SCALE;
  312.    temp  = ((color1 >> 4) & 0x00f) - ((color2 >> 4) & 0x00f);
  313.    diff += temp * temp * GREEN_SCALE;
  314.    temp  = ((color1 >> 8) & 0x00f) - ((color2 >> 8) & 0x00f);
  315.    diff += temp * temp * RED_SCALE;
  316.    return(diff);
  317. }
  318.     /* Init render info images */
  319.  
  320.    STATIC VOID
  321. init_render_info_images(struct RenderInfo *ri)
  322. {
  323.    struct Image  *image_src = &images[0], *image_dest = &ri->ri_Images[0];
  324.    UBYTE  color;
  325.    USHORT i, x, y, *data = ri->ri_ImageData;
  326.  
  327.    CopyMem((BYTE *)image_src, (BYTE *)image_dest, (LONG)(MAX_RENDER_IMAGES *
  328.                              sizeof(struct Image)));
  329.    for (i = 0; i < MAX_RENDER_IMAGES; i++, image_src++, image_dest++) {
  330.       image_dest->Depth = ri->ri_ScreenDepth;
  331.       if (image_src->ImageData) {
  332.  
  333.      /* Set data buffer ptr */
  334.      image_dest->ImageData = data;
  335.      image_dest->PlanePick = (1 << image_dest->Depth) - 1;
  336.      data += (image_dest->Width / 16 + (image_dest->Width & 15 ? 1 :
  337.                    0)) * image_dest->Height * image_dest->Depth;
  338.      /* Convert image data */
  339.      for (y = 0; y < image_src->Height; y++) {
  340.         for (x = 0; x < image_src->Width; x++) {
  341.            switch(get_image_pixel_color(image_src, x, y)) {
  342.           case 0 :   /* back pen */
  343.              color = ri->ri_BackPen;
  344.              break;
  345.           case 1 :   /* highlight pen */
  346.              color = ri->ri_HighlightPen;
  347.              break;
  348.           case 2 :   /* shadow pen */
  349.              color = ri->ri_ShadowPen;
  350.              break;
  351.           case 3 :   /* special pen */
  352.              color = ri->ri_TextPen2;
  353.              break;
  354.            }
  355.            set_image_pixel_color(image_dest, x, y, color);
  356.         }
  357.      }
  358.       } else {
  359.  
  360.      /* No image data -> monochrome rectangle */
  361.      switch(image_src->PlaneOnOff) {
  362.         case 0 :   /* back pen */
  363.            color = ri->ri_BackPen;
  364.            break;
  365.         case 1 :   /* highlight pen */
  366.            color = ri->ri_HighlightPen;
  367.            break;
  368.         case 2 :   /* shadow pen */
  369.            color = ri->ri_ShadowPen;
  370.            break;
  371.         case 3 :   /* special pen */
  372.            color = ri->ri_TextPen2;
  373.            break;
  374.      }
  375.      image_dest->PlaneOnOff = color;
  376.       }
  377.    }
  378. }
  379.     /* Get color of image pixel */
  380.  
  381.    STATIC UBYTE
  382. get_image_pixel_color(struct Image  *image, USHORT x, USHORT y)
  383. {
  384.    UBYTE  i, depth = image->Depth, color_mask = 1, color = 0;
  385.    USHORT modulo = image->Width / 16 + (image->Width & 15 ? 1 : 0),
  386.       *data = image->ImageData + y * modulo + x / 16,
  387.       bit_mask = 0x8000 >> (x & 15);
  388.  
  389.    for (i = 0; i < depth; i++, data += image->Height * modulo,
  390.                              color_mask <<= 1) {
  391.       if (*data & bit_mask) {
  392.      color |= color_mask;
  393.       }
  394.    }
  395.    return(color);
  396. }
  397.     /* Set color of image pixel */
  398.  
  399.    STATIC VOID
  400. set_image_pixel_color(struct Image  *image, USHORT x, USHORT y, UBYTE color)
  401. {
  402.    UBYTE  i, depth = image->Depth;
  403.    USHORT modulo = image->Width / 16 + (image->Width & 15 ? 1 : 0),
  404.       *data = image->ImageData + y * modulo + x / 16,
  405.       bit_mask = 0x8000 >> (x & 15);
  406.  
  407.    for (i = 0; i < depth; i++, data += image->Height * modulo, color >>= 1) {
  408.       if (color & 1) {
  409.      *data |= bit_mask;
  410.       }
  411.    }
  412. }
  413.     /* Free render info */
  414.  
  415.    VOID
  416. free_render_info(struct RenderInfo  *ri)
  417. {
  418.    if (ri) {
  419.       if (ri->ri_TextFont) {
  420.      CloseFont(ri->ri_TextFont);
  421.       }
  422.       FreeMem(ri->ri_ImageData, ri->ri_ImageDataSize);
  423.       FreeMem(ri, (LONG)sizeof(struct RenderInfo));
  424.    }
  425. }
  426.     /* Open window */
  427.  
  428.    struct Window *
  429. open_window(struct RenderInfo  *ri, struct NewWindow  *org_nw, USHORT flags)
  430. {
  431.    struct NewWindow  *nw, new_nw;
  432.    struct Window     *win = NULL;
  433.  
  434.    if (ri && org_nw) {
  435.  
  436.       /* Duplicate given new window struct */
  437.       CopyMem((BYTE *)org_nw, (BYTE *)(nw = &new_nw), (LONG)
  438.                           sizeof(struct NewWindow));
  439.       /* Scale new window dimension */
  440.       if (nw->Width > ri->ri_ScreenWidth) {
  441.      nw->LeftEdge = 0;
  442.      nw->Width    = ri->ri_ScreenWidth;
  443.       } else {
  444.      if ((nw->LeftEdge + nw->Width) > ri->ri_ScreenWidth) {
  445.         nw->LeftEdge = ri->ri_ScreenWidth - nw->Width;
  446.      }
  447.       }
  448.       if (nw->Height > ri->ri_ScreenHeight) {
  449.      nw->TopEdge = 0;
  450.      nw->Height  = ri->ri_ScreenHeight;
  451.       } else {
  452.      if ((nw->TopEdge + nw->Height) > ri->ri_ScreenHeight) {
  453.         nw->TopEdge = ri->ri_ScreenHeight - nw->Height;
  454.      }
  455.       }
  456.  
  457.       /* Change new window struct */
  458.       if (flags & OPEN_WINDOW_FLAG_CENTER_WINDOW) {
  459.      nw->LeftEdge = (ri->ri_ScreenWidth - nw->Width) / 2;
  460.      nw->TopEdge  = (ri->ri_ScreenHeight - nw->Height) / 2;
  461.       }
  462.       if (flags & OPEN_WINDOW_FLAG_RENDER_PENS) {
  463.      if (ri->ri_Flags & RENDER_INFO_FLAG_BACK_FILL) {
  464.         nw->DetailPen = ri->ri_TextPen1;
  465.         nw->BlockPen  = ri->ri_BackPen;
  466.      } else {
  467.         nw->DetailPen = ri->ri_BackPen;
  468.         nw->BlockPen  = ri->ri_TextPen1;
  469.      }
  470.       }
  471.       if (ri->ri_Flags & RENDER_INFO_FLAG_INNER_WINDOW) {
  472.      nw->Width += ri->ri_WindowBorderLeft + ri->ri_WindowBorderRight;
  473.      if ((nw->LeftEdge + nw->Width) > ri->ri_ScreenWidth) {
  474.         nw->Width = ri->ri_ScreenWidth - nw->LeftEdge;
  475.      }
  476.      nw->Height += ri->ri_WindowBorderTop + ri->ri_WindowBorderBottom;
  477.      if ((nw->TopEdge + nw->Height) > ri->ri_ScreenHeight) {
  478.         nw->Height = ri->ri_ScreenHeight - nw->TopEdge;
  479.      }
  480.       }
  481.       if (win = OpenWindow(nw)) {
  482.      if (ri->ri_Flags & RENDER_INFO_FLAG_BACK_FILL) {
  483.         clear_render_window(ri, win, 0, 0, nw->Width, nw->Height);
  484.      }
  485.       }
  486.    }
  487.    return(win);
  488. }
  489.     /* Clear given rectangle of window with data from render info */
  490.  
  491.    VOID
  492. clear_render_window(struct RenderInfo  *ri, struct Window  *win,
  493.          USHORT left_edge, USHORT top_edge, USHORT width, USHORT height)
  494. {
  495.    struct RastPort  *rp = win->RPort;
  496.    USHORT inner_left, inner_top, inner_width, inner_height, back_pen,
  497.       flags = ri->ri_Flags;
  498.  
  499.    /* Calc inner window dimension */
  500.    if ((flags & RENDER_INFO_FLAG_INNER_WINDOW) ||
  501.                      (flags & RENDER_INFO_FLAG_BACK_FILL)) {
  502.       inner_left   = ri->ri_WindowBorderLeft;
  503.       inner_top    = ri->ri_WindowBorderTop;
  504.       inner_width  = win->Width - inner_left - ri->ri_WindowBorderRight;
  505.       inner_height = win->Height - inner_top - ri->ri_WindowBorderBottom;
  506.    } else {
  507.       inner_left   = 0;
  508.       inner_top    = 0;
  509.       inner_width  = win->Width;
  510.       inner_height = win->Height;
  511.    }
  512.  
  513.    /* Check if given rectangle fits into inner window and if not then scale it */
  514.    if ((SHORT)left_edge >= 0 && (SHORT)top_edge >= 0 && width && height &&
  515.        left_edge < (inner_left + inner_width) && top_edge < (inner_top +
  516.                                 inner_height)) {
  517.       if (left_edge < inner_left) {
  518.      left_edge  = inner_left;
  519.       } else {
  520.      left_edge += inner_left;
  521.       }
  522.       if (top_edge < inner_top) {
  523.      top_edge  = inner_top;
  524.       } else {
  525.      top_edge += inner_top;
  526.       }
  527.       if ((SHORT)width <= 0 || (left_edge + width) > (inner_left +
  528.                                  inner_width)) {
  529.      width = inner_left + inner_width - left_edge;
  530.       }
  531.       if ((SHORT)height <= 0 || (top_edge + height) > (inner_top +
  532.                                 inner_height)) {
  533.      height = inner_top + inner_height - top_edge;
  534.       }
  535.       if (flags & RENDER_INFO_FLAG_BACK_FILL) {
  536.      back_pen = ri->ri_BackPen;
  537.       } else {
  538.      back_pen = 0;
  539.       }
  540.       SetDrMd(rp, (LONG)JAM1);
  541.       SetAPen(rp, (LONG)back_pen);
  542.       RectFill(rp, (LONG)left_edge, (LONG)top_edge, (LONG)(left_edge +
  543.                  width - 1), (LONG)(top_edge + height - 1));
  544.    }
  545. }
  546.